package com.whut.coc.util;

import lombok.NoArgsConstructor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @Description:
 * @Author: Zonghe Wang
 * @Date: 2025/6/22 14:21
 */
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public class HttpUtils {

    /**
     * 发送 GET 请求
     * @param url     请求地址
     * @param headers 请求头 (可为null)
     * @return 响应内容
     * @throws IOException 网络异常
     */
    public static String get(String url, Map<String, String> headers) throws IOException {
        return sendRequest("GET", url, headers, null);
    }

    /**
     * 发送 POST 请求 (JSON格式)
     * @param url     请求地址
     * @param headers 请求头 (可为null)
     * @param json    JSON字符串
     * @return 响应内容
     * @throws IOException 网络异常
     */
    public static String postJson(String url, Map<String, String> headers, String json) throws IOException {
        if (headers != null) {
            headers.put("Content-Type", "application/json");
        }
        return sendRequest("POST", url, headers, json);
    }

    /**
     * 发送 POST 请求 (表单格式)
     * @param url    请求地址
     * @param headers 请求头 (可为null)
     * @param params 表单参数 (key=value&key2=value2)
     * @return 响应内容
     * @throws IOException 网络异常
     */
    public static String postForm(String url, Map<String, String> headers, Map<String, String> params) throws IOException {
        if (headers != null) {
            headers.put("Content-Type", "application/x-www-form-urlencoded");
        }
        return sendRequest("POST", url, headers, buildFormData(params));
    }

    /**
     * 发送 PUT 请求
     * @param url     请求地址
     * @param headers 请求头 (可为null)
     * @param data    请求体数据
     * @return 响应内容
     * @throws IOException 网络异常
     */
    public static String put(String url, Map<String, String> headers, String data) throws IOException {
        return sendRequest("PUT", url, headers, data);
    }

    /**
     * 发送 DELETE 请求
     * @param url     请求地址
     * @param headers 请求头 (可为null)
     * @return 响应内容
     * @throws IOException 网络异常
     */
    public static String delete(String url, Map<String, String> headers) throws IOException {
        return sendRequest("DELETE", url, headers, null);
    }

    /**
     * 核心请求方法
     * @param method  请求方法 (GET/POST/PUT/DELETE)
     * @param url     请求地址
     * @param headers 请求头
     * @param body    请求体数据 (可为null)
     * @return 响应内容
     * @throws IOException 网络异常
     */
    private static String sendRequest(String method, String url,
                                      Map<String, String> headers,
                                      String body) throws IOException {
        HttpURLConnection conn = null;
        try {
            // 创建连接
            URL requestUrl = new URL(url);
            conn = (HttpURLConnection) requestUrl.openConnection();

            // 设置通用参数
            conn.setRequestMethod(method);
            // 5秒连接超时
            conn.setConnectTimeout(5000);
            // 10秒读取超时
            conn.setReadTimeout(10000);
            conn.setDoInput(true);

            // 设置请求头
            if (headers != null) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }

            // 处理请求体 (POST/PUT)
            if (body != null && !body.isEmpty() &&
                    ("POST".equals(method) || "PUT".equals(method))) {
                conn.setDoOutput(true);
                try (OutputStream os = conn.getOutputStream()) {
                    byte[] input = body.getBytes(StandardCharsets.UTF_8);
                    os.write(input, 0, input.length);
                }
            }

            // 获取响应状态码
            int status = conn.getResponseCode();

            // 读取响应内容
            try (BufferedReader br = new BufferedReader(
                    new InputStreamReader(
                            (status >= 200 && status < 300) ?
                                    conn.getInputStream() : conn.getErrorStream(),
                            StandardCharsets.UTF_8
                    )
            )) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            }
        } finally {
            if (conn != null) {
                // 断开连接
                conn.disconnect();
            }
        }
    }

    /**
     * 构建表单数据字符串
     * @param params 参数Map
     * @return 表单字符串 (key1=value1&key2=value2)
     */
    private static String buildFormData(Map<String, String> params) {
        if (params == null || params.isEmpty()) return "";

        StringBuilder formData = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (!formData.isEmpty()) formData.append("&");
            formData.append(entry.getKey())
                    .append("=")
                    .append(entry.getValue());
        }
        return formData.toString();
    }
}
